home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Power Programmierung
/
Power-Programmierung (Tewi)(1994).iso
/
magazine
/
pcmagazi
/
utility
/
chain
/
chain.asm
next >
Wrap
Assembly Source File
|
1987-11-17
|
12KB
|
262 lines
DATA SEGMENT WORD PUBLIC
EXTRN PrefixSeg:WORD
EXTRN SaveInt00:DWORD
EXTRN SaveInt02:DWORD
EXTRN SaveInt23:DWORD
EXTRN SaveInt24:DWORD
EXTRN SaveInt75:DWORD
DATA ENDS
CODE SEGMENT BYTE PUBLIC
ASSUME CS:Code,DS:Data
PUBLIC Chain4
;This generates a bunch of NOPs in object
;CodeLen = offset Dummy-offset CodeToRelocate ;Length of code in PSP
;MaxCmdLen = 07Eh-CodeLen ;Maximum length of command line
;These values must be exact
;They'll need changing if anything after label CodeToRelocate changes
CodeLen EQU 01Fh
MaxCmdLen EQU 05Fh
;**************************************************************** Chain4
; procedure Chain4(Path, CmdLine : String);
; Turbo 4 equivalent of chaining
;Parameters
PathArg EQU DWORD PTR [BP+10]
CmdLine EQU DWORD PTR [BP+6]
;Local variables
CsInit EQU WORD PTR [BP-30+16h] ;Fields within EXE header
IpInit EQU WORD PTR [BP-30+14h]
StackPtr EQU WORD PTR [BP-30+10h]
StackSeg EQU WORD PTR [BP-30+0Eh]
EXEHeader EQU WORD PTR [BP-30] ;EXE header from file
Path EQU BYTE PTR [BP-94] ;ASCIIZ path string
Chain4 PROC FAR
PUSH BP
MOV BP,SP ;Set up stack frame
SUB SP,94 ;Make space for locals
;Validate pathname and convert to ASCIIZ
PUSH DS ;Save DS for later
PUSH SS
POP ES ;ES = SS
LEA DI,Path ;ES:DI => ASCIIZ path
MOV BX,DI ;Save offset of ASCIIZ
LDS SI,PathArg ;DS:SI => file path in Turbo string
ASSUME DS:nothing
CLD ;Forward
LODSB ;Get length byte
CMP AL,63 ;Longer than 63 characters?
JB StoreASCIIZ
MOV AL,63 ;Truncate it
StoreASCIIZ:
MOV CL,AL ;CX = length
XOR CH,CH
REP MOVSB ;Copy to local Path
XOR AL,AL ;Make ASCIIZ
STOSB
;Assure file exists
PUSH SS
POP DS ;DS = SS
MOV DX,BX ;DS:DX => ASCIIZ path
MOV AX,3D00h ;Open file read-only
INT 21h
JNC FileFound ;OK, file was found
Error: POP DS ;Restore DS
ASSUME DS:Data
Error1: MOV SP,BP ;Return with error code in AX
POP BP ;Restore BP
RET 8 ;Remove parameters from stack
;Read header and close file
FileFound:
MOV BX,AX ;BX = file handle
LEA DX,ExeHeader ;DS:DX => ExeHeader
MOV CX,28 ;Read 28 bytes
MOV AH,3Fh ;DOS read file
INT 21h
JC Error ;Error if carry set
CMP AX,CX
MOV AX,30 ;Prepare for Read Fault error
JNE Error ;Error if 28 bytes not read
MOV AH,3Eh ;Close file
INT 21h
JC Error ;Error if carry set
;Allocate all available memory to this process
POP DS ;Restore DS
ASSUME DS:Data
MOV ES,PrefixSeg ;Main program segment
MOV AH,4Ah ;Setblock
MOV BX,0FFFFh ;Ask for everything
INT 21h
MOV AH,4Ah ;Ask again for what we can get
INT 21h
JC Error1 ;Error if carry set now
;Prepare to move stack to top of memory
MOV AX,ES ;Base of program
ADD AX,BX ;Add all available paragraphs
SUB AX,1000h ;Room for full segment
MOV CS:TmpSS,AX ;Store temporary SS
;Close secondary file handles (don't touch StdIn,StdOut,StdErr)
MOV BX,3 ;Start with handle 3
MOV CX,17 ;17 handles max
NextHandle:
MOV AH,3Eh ;DOS close file
INT 21h
INC BX ;Ignore errors
LOOP NextHandle
;Restore interrupt vectors taken over by SYSTEM library
MOV CX,DS ;Save DS
MOV AX,2500h ;Restore INT 00
LDS DX,SaveInt00 ;Get saved vector
ASSUME DS:Nothing
INT 21h
MOV DS,CX ;Restore DS
ASSUME DS:Data
MOV AL,02h ;Restore INT 02
LDS DX,SaveInt02 ;Get saved vector
ASSUME DS:Nothing
INT 21h
MOV DS,CX ;Restore DS
ASSUME DS:Data
MOV AL,23h ;Restore INT 23
LDS DX,SaveInt23 ;Get saved vector
ASSUME DS:Nothing
INT 21h
MOV DS,CX ;Restore DS
ASSUME DS:Data
MOV AL,24h ;Restore INT 24
LDS DX,SaveInt24 ;Get saved vector
ASSUME DS:Nothing
INT 21h
MOV DS,CX ;Restore DS
ASSUME DS:Data
MOV AL,75h ;Restore INT 75
LDS DX,SaveInt75 ;Get saved vector
ASSUME DS:Nothing
INT 21h
;Set up command line for chained program
LDS SI,CmdLine ;DS:SI points to command line
MOV DI,80h ;ES:DI => command line in PSP
LODSB ;Get length byte
CMP AL,MaxCmdLen ;Is is too long?
JB StoreCmdLine ;No, don't truncate
MOV AL,MaxCmdLen ;Truncate
StoreCmdLine:
STOSB ;Store length byte
MOV BX,DI ;Save start of command line
MOV CL,AL
XOR CH,CH
REP MOVSB ;Copy parameter to command line
MOV AL,0Dh ;Terminate with <Enter>
STOSB
;Initialize FCB's for new program
PUSH ES
POP DS ;DS = ES
MOV SI,BX ;DS:SI => command line to parse
MOV DI,005Ch ;ES:DI => FCB1
MOV AX,2901h ;Init FCB1
INT 21h
MOV DI,006Ch ;ES:DI => FCB2
MOV AX,2901h ;Init FCB2
INT 21h
;Save initialization data for new program
MOV BX,ES ;Store prefix seg in BX
MOV CS:NewCS,BX ;Assume COM file
MOV CS:NewSS,BX
ADD BX,10h ;BX = base segment
CMP ExeHeader,5A4Dh ;Is it EXE format?
JNE MoveCode ;No, COM file already initialized
MOV AX,CsInit ;Get initial CS from EXE header,
ADD AX,BX ; relocate segment,
MOV CS:NewCS,AX ; write to code in PSP
MOV AX,IpInit ;Initial IP
MOV CS:NewIP,AX
MOV AX,StackSeg ;Initial SS
ADD AX,BX
MOV CS:NewSS,AX
MOV AX,StackPtr ;Initial SP
MOV CS:NewSP,AX
;Move code into PSP
MoveCode:
MOV CX,CodeLen ;Bytes to move
MOV DI,100h ;DI => end of new code
SUB DI,CX ;ES:DI => destination of new code
MOV CS:TmpIP,DI ;Store address to jump to
MOV CS:TmpCS,ES
PUSH CS
POP DS ;DS = CS
MOV SI,offset CodeToRelocate ;DS:SI => code to relocate
REP MOVSB ;Copy the code to PSP
;Prepare for EXEC call
MOV AX,BX ;AX = Base segment
STOSW
STOSW ;Initialize EXEC block
PUSH SS
POP DS ;DS = SS
LEA DX,Path ;DS:DX => Path of file
MOV BX,100h ;ES:BX => EXEC block
MOV AX,4B03H ;Load Overlay
CLI
MOV SS,CS:TmpSS ;Put stack at top
MOV SP,0FFFEh ; of memory
STI
DB 0EAh ;JMP FAR to code in PSP
TmpIP DW 0 ;Patched in with offset
TmpCS DW 0 ;Patched in with segment
TmpSS DW 0 ;Temporary stack segment
;-----------------------------------------------------------------------------
;Code executed in PSP
CodeToRelocate:
INT 21h ;Call DOS EXEC
JNC GoodLoad ;Check for error
INT 20h ;Error shouldn't happen,
; just halt if EXEC failed
GoodLoad:
MOV AX,CS ;Get base of program
MOV DS,AX ;Initialize DS
MOV ES,AX ;Initialize ES
CLI ;Interrupts off
MOV SS,DS:[0FEh] ;Initialize stack
MOV SP,DS:[0FCh]
STI ;Interrupts on again
DB 0EAh ;JMP FAR to start of code
NewIP DW 100h ;Patched in with start offset
NewCS DW 0 ;Patched in with start segment
NewSP DW 0FFFEh ;Patched in with new SP
NewSS DW 0 ;Patched in with new SS
Chain4 ENDP
Dummy LABEL BYTE
CODE ENDS
END